package com.zd.mock.huyisen;

import com.github.javafaker.Faker;

import java.sql.*;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.math.BigDecimal;


public class VisitorOrderDataGenerator {
    private static final String DB_URL = "jdbc:mysql://hadoop102:3306/zhengzhou_tourism_business?useSSL=false&serverTimezone=UTC";
    private static final String DB_USER = "root";
    private static final String DB_PASSWORD = "000000";
    private static final int BATCH_SIZE = 100;
    private static final Faker faker = new Faker(new Locale("zh-CN"));
    private static final Random random = new Random();

    public static void main(String[] args) {
        int count = 1000;
        generateVisitorOrders(count);
    }

    public static void generateVisitorOrders(int count) {
        String insertSql = "INSERT INTO visitor_orders (order_id, visitor_phone, visitor_name, order_type, order_amount, order_status, payment_time, create_time, update_time) " +
                "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";

        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
             PreparedStatement pstmt = conn.prepareStatement(insertSql)) {

            conn.setAutoCommit(false);

            for (int i = 1; i <= count; i++) {
                String orderId = generateOrderId(i);
                String phone = generatePhoneNumber();
                String name = faker.name().fullName(); // 中文姓名
                int orderType = random.nextInt(4) + 1; // 1~4
                double amount = generateAmount(orderType);
                int status = random.nextBoolean() ? 1 : 0;

                LocalDateTime createTime = randomDateTimeBetweenDays(90); // 最近90天
                LocalDateTime paymentTime = status == 1 ? createTime.plusMinutes(random.nextInt(60)) : null;
                LocalDateTime updateTime = paymentTime != null ? paymentTime : createTime;

                pstmt.setString(1, orderId);
                pstmt.setString(2, phone);
                pstmt.setString(3, name);
                pstmt.setInt(4, orderType);
                pstmt.setBigDecimal(5, BigDecimal.valueOf(amount));
                pstmt.setInt(6, status);
                if (paymentTime != null) {
                    pstmt.setTimestamp(7, Timestamp.valueOf(paymentTime));
                } else {
                    pstmt.setNull(7, Types.TIMESTAMP);
                }
                pstmt.setTimestamp(8, Timestamp.valueOf(createTime));
                pstmt.setTimestamp(9, Timestamp.valueOf(updateTime));

                pstmt.addBatch();
                if (i % BATCH_SIZE == 0) {
                    pstmt.executeBatch();
                }
            }

            pstmt.executeBatch();
            conn.commit();
            System.out.println("成功插入 " + count + " 条 visitor_orders 数据");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 生成订单编号：ORD + 年月日 + 4位序号
    private static String generateOrderId(int index) {
        LocalDateTime now = LocalDateTime.now();
        return String.format("ORD%04d%02d%02d%04d", now.getYear(), now.getMonthValue(), now.getDayOfMonth(), index);
    }

    // 生成符合中国规范的手机号
    private static String generatePhoneNumber() {
        String[] prefixes = {"138", "139", "137", "136", "135", "150", "151", "152", "157", "158", "159", "188", "187"};
        String prefix = prefixes[random.nextInt(prefixes.length)];
        String suffix = String.format("%08d", random.nextInt(100000000));
        return prefix + suffix;
    }

    // 模拟不同类型对应金额范围
    private static double generateAmount(int type) {
        switch (type) {
            case 1: return 100 + random.nextInt(200); // 门票
            case 2: return 300 + random.nextInt(500); // 住宿
            case 3: return 50 + random.nextInt(300);  // 购物
            case 4: return 200 + random.nextInt(400); // 路线
            default: return 100;
        }
    }

    // 生成指定范围内的随机时间
    private static LocalDateTime randomDateTimeBetweenDays(int pastDays) {
        long min = LocalDateTime.now().minusDays(pastDays).atZone(ZoneId.systemDefault()).toEpochSecond();
        long max = LocalDateTime.now().atZone(ZoneId.systemDefault()).toEpochSecond();
        long randomEpoch = min + (long) (Math.random() * (max - min));
        return LocalDateTime.ofEpochSecond(randomEpoch, 0, ZoneId.systemDefault().getRules().getOffset(LocalDateTime.now()));
    }
}
